package com.demo.base.util;

import cn.hutool.core.io.FileTypeUtil;
import com.demo.base.exception.AiException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * @author 曳戈泰尔
 * @version 1.0
 * @description 图片属性限制
 * @date 2023/3/25 4:10 PM
 */
@Slf4j
public class ImagePropertyLimitUtil {

    /** 支持的图片格式 */
    private static final Set<String> FORMAT_SET =
            new HashSet<>(Arrays.asList("JPG", "JPEG", "PNG"));

    /**
     * 检测图片合法性，校验尺寸，格式，像素
     *
     * @param file
     */
    public static void propertyLimit(MultipartFile file) {

        limitByFormat(file);
    }

    /**
     * 限制大小
     *
     * @param file
     * @return
     */
    public static Boolean limitBySize(MultipartFile file) {

        // 单位换算为M
        double fileSize = (double) file.getSize() / 1048576;

        if (fileSize >= 20) {
            log.error("图片大小错误，大小为：{}", fileSize);

            throw new AiException("图片文件大小请小于20MB");
        }

        return true;
    }

    /**
     * 通过格式限制图片
     *
     * @param file
     * @return
     */
    public static Boolean limitByFormat(MultipartFile file) {

        try {
            // 获取文件类型，后缀
            String type = FileTypeUtil.getType(file.getInputStream());

            // 获取文件类型
            String contentType = file.getContentType();

            if (StringUtils.isBlank(contentType)) {
                log.error("图片格式获取失败，结果为空");

                throw new AiException("网络错误，请重试");
            }

            // 判断content type是不是image
            if (!"image".equals(contentType.substring(0, contentType.indexOf("/")))) {
                log.error("图片格式错误，不是image");

                throw new AiException("请上传正确的图片文件格式类型");
            }

            if (type == null) {
                log.error("图片格式获取失败，结果为空");

                throw new AiException("请上传正确的图片文件格式类型");
            }

            if (!FORMAT_SET.contains(type.toUpperCase())) {
                log.error("图片格式错误，图片格式为：{}", type);

                throw new AiException("请上传正确的图片文件格式类型");
            }

        } catch (IOException e) {
            log.error("图片格式获取失败，异常：{}", e.getMessage());

            throw new AiException("网络错误，请重试");
        }

        return true;
    }

    /**
     * 限制像素值
     *
     * @param file
     * @return
     */
    public static Boolean limitByResolution(MultipartFile file) {

        try {
            Image img = ImageIO.read(file.getInputStream());

            if (img == null) {
                log.error("图片像素获取失败");

                throw new AiException("网络错误，请重试");
            }

            if (!(img.getWidth(null) > 128 && img.getHeight(null) > 128)) {
                log.error("图片像素非法，宽：{}", img.getWidth(null));

                throw new AiException("图片长和宽要大于128像素");
            }

            if (!(img.getWidth(null) < 2000 && img.getHeight(null) < 2000)) {
                log.error("图片像素非法，高：{}", img.getHeight(null));

                throw new AiException("图片长和宽要小于2000像素");
            }

        } catch (IOException e) {
            log.error("图片像素获取失败，异常：{}", e.getMessage());

            throw new AiException("网络错误，请重试");
        }

        return true;
    }
}
